﻿using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using System.Reflection;
using TVMCORP.TVS.UTIL.Helpers;
using TVMCORP.TVS.UTIL.Extensions;
using TVMCORP.TVS.UTIL.MODELS;
using TVMCORP.TVS.UTIL;
using TVMCORP.TVS.UTIL.Utilities;
using Microsoft.SharePoint.Navigation;
using System.Linq;

namespace TVMCORP.TVS.Features.TVMCORP.TVS.Feature
{
    /// <summary>
    /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
    /// </summary>
    /// <remarks>
    /// The GUID attached to this class may be used during packaging and should not be modified.
    /// </remarks>

    [Guid("3b2bdbd0-81c9-435b-b5a8-d052bad2198a")]
    public class TVMCORPTVSEventReceiver : SPFeatureReceiver
    {
        // Uncomment the method below to handle the event raised after a feature has been activated.

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPWeb web = (SPWeb)properties.Feature.Parent;
            try
            {
                SetListPermission(web);
                //RemoveXsltListViewWebPart(web.Site.MakeFullUrl(Constants.PURCHASE_MY_ITEM_VIEW_URL), web);
                //RemoveXsltListViewWebPart(web.Site.MakeFullUrl(Constants.PURCHASE_MY_DEPARTMENT_ITEM_VIEW_URL), web);
                ProvisionWebParts(web, "TVMCORP.TVS.WebParts.xml");

                ConfigLists(web);

                EnsurePermissionLevel(web);

                CreateQuickLauch(web);

                var folder = web.RootFolder;
                folder.WelcomePage = "SitePages/Request.aspx";
                folder.Update();
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, TVMCORPFeatures.TVS);
            }
        }


        // Uncomment the method below to handle the event raised before a feature is deactivated.

        //public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        //{
        //}


        // Uncomment the method below to handle the event raised after a feature has been installed.

        //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        //{
        //}


        // Uncomment the method below to handle the event raised before a feature is uninstalled.

        //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        //{
        //}

        // Uncomment the method below to handle the event raised when a feature is upgrading.

        //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
        //{
        //}

        #region Functions

        private void EnsurePermissionLevel(SPWeb web)
        {
            try
            {
                SPRoleDefinition role = null;
                var iOfficeContributeRole = web.Site.RootWeb.RoleDefinitions.Cast<SPRoleDefinition>().FirstOrDefault(p => p.Name == Constants.CONTRIBUTE_NOT_DELETE_PERMISSION_LEVEL);
                if (iOfficeContributeRole == null)
                {
                    role = new SPRoleDefinition();
                    role.BasePermissions = SPBasePermissions.BrowseDirectories |
                        SPBasePermissions.Open |
                        SPBasePermissions.OpenItems |
                        SPBasePermissions.ViewListItems |
                        SPBasePermissions.ViewFormPages |
                        SPBasePermissions.EditListItems |
                        SPBasePermissions.AddListItems |
                        SPBasePermissions.ApproveItems |
                        SPBasePermissions.ViewPages |
                        SPBasePermissions.CancelCheckout |
                        SPBasePermissions.ViewVersions;
                    role.Name = Constants.CONTRIBUTE_NOT_DELETE_PERMISSION_LEVEL;
                    role.Description = Constants.CONTRIBUTE_NOT_DELETE_PERMISSION_LEVEL_DESCRIPTION;
                    web.Site.RootWeb.RoleDefinitions.Add(role);
                }
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, "Ensure Permission Level");
            }
        }

        private void SetListPermission(SPWeb web)
        {
            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite site = new SPSite(web.Site.ID))
                    {
                        using (SPWeb spWeb = site.OpenWeb(web.ID))
                        {
                            spWeb.AllowUnsafeUpdates = true;
                            //Purchase list
                            var purchaseList = Utility.GetListFromURL(Constants.REQUEST_LIST_URL, spWeb);
                            purchaseList.BreakRoleInheritance(false);
                            purchaseList.SetPermissions(spWeb.EnsureUser(Constants.AUTHENTICATED_USERS), SPRoleType.Contributor);
                            //Purchase Detail list
                            var RequestDetailList = Utility.GetListFromURL(Constants.REQUEST_DETAIL_LIST_URL, spWeb);
                            RequestDetailList.BreakRoleInheritance(false);
                            RequestDetailList.SetPermissions(spWeb.EnsureUser(Constants.AUTHENTICATED_USERS), SPRoleType.Contributor);
                            //Purchase Task List
                            var purchaseTaskApprovalList = Utility.GetListFromURL(Constants.REQUEST_TASK_LIST_URL, spWeb);
                            purchaseTaskApprovalList.BreakRoleInheritance(false);
                            purchaseTaskApprovalList.SetPermissions(spWeb.EnsureUser(Constants.AUTHENTICATED_USERS), SPRoleType.Reader);
                            spWeb.AllowUnsafeUpdates = true;
                            //Discussion List
                            var discussionlList = Utility.GetListFromURL(Constants.DISCUSSIONS_LIST_URL, spWeb);
                            discussionlList.BreakRoleInheritance(false);
                            discussionlList.SetPermissions(spWeb.EnsureUser(Constants.AUTHENTICATED_USERS), SPRoleType.Contributor);
                            spWeb.AllowUnsafeUpdates = true;
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, TVMCORPFeatures.TVS);
            }
        }


        private void RemoveXsltListViewWebPart(string fullPageUrl, SPWeb spWeb)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(spWeb.Site.ID))
                {
                    using (SPWeb web = site.OpenWeb(spWeb.ID))
                    {
                        web.AllowUnsafeUpdates = true;
                        Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager webPartManager = web.GetLimitedWebPartManager(fullPageUrl, System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);

                        foreach (System.Web.UI.WebControls.WebParts.WebPart webPart in webPartManager.WebParts)
                        {
                            if (webPart is Microsoft.SharePoint.WebPartPages.XsltListViewWebPart)//|| webPart is ListViewWebPart)
                            {
                                //webPartManager.MoveWebPart(webPart, "Main", 0);
                                webPartManager.DeleteWebPart(webPart);
                                //webPart.Hidden = true;
                                //webPartManager.SaveChanges(webPart);
                                web.Update();
                                break;
                            }
                        }
                        web.AllowUnsafeUpdates = false;
                    }
                }
            });
        }

        private void ProvisionWebParts(SPWeb web, string xmlFile)
        {
            try
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                string xml = assembly.GetResourceTextFile(xmlFile);

                var webpartPages = SerializationHelper.DeserializeFromXml<WebpartPageDefinitionCollection>(xml);
                WebPartHelper.ProvisionWebpart(web, webpartPages);
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, TVMCORPFeatures.TVS);
            }
        }

        private void ConfigLists(SPWeb web)
        {
            try
            {
                web.AllowUnsafeUpdates = true;

                SPList listPurchase = Utility.GetListFromURL(Constants.REQUEST_LIST_URL, web);
                if (listPurchase != null)
                {
                    //SetListProperties(listPurchase, true);
                    CreateApprovalWorkflow(listPurchase, "[TVS] Approval Workflow", "Request Approval", "TVMCORP.TVS.XMLSettings.ApprovalWorkflowSettings_Purchase.xml");
                }
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, TVMCORPFeatures.TVS);
            }
            finally
            {
                web.AllowUnsafeUpdates = false;
            }
        }

        private void SetListProperties(SPList list, bool enableContentApproval)
        {
            try
            {
                list.ParentWeb.AllowUnsafeUpdates = true;

                list.ContentTypesEnabled = true;
                list.EnableVersioning = true;

                if (enableContentApproval)
                    list.EnableModeration = true; //enable Content Approval, Approval Status column will be added to default view

                list.Update();

                if (enableContentApproval)
                {
                    SPView view = list.DefaultView;
                    view.ViewFields.Delete("_ModerationStatus");
                    view.Update();
                }
            }
            catch (Exception ex)
            {
                Utility.LogError(ex.Message, TVMCORPFeatures.TVS);
            }
            finally
            {
                list.ParentWeb.AllowUnsafeUpdates = false;
            }
        }

        private void CreateApprovalWorkflow(SPList list, string workflowTemplateName, string workflowName, string fileSettings)
        {
            string association = string.Empty;

            if (!string.IsNullOrEmpty(fileSettings))
            {
                Assembly assembly = Assembly.GetExecutingAssembly();
                string xml = assembly.GetResourceTextFile(fileSettings);

                association = SerializationHelper.SerializeToXml(SerializationHelper.DeserializeFromXml<ApprovalWFAssociationData>(xml));
            }

            list.AssociateWorkflow(workflowTemplateName, workflowName, association, "Duyệt đề nghị");
        }

        private void CreateQuickLauch(SPWeb web)
        {
            try
            {
                string headingTitle = "Đề nghị";
                string headingUrl = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/Request.aspx";

                string purchase = "Mua hàng";
                string purchaseUrl = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/Purchase.aspx";

                string purchaseCEO = "Mua hàng CEO";
                string purchaseUrlCEO = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/PurchaseCEO.aspx";

                string payment = "Thanh toán";
                string paymentUrl = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/Payment.aspx";

                string advancePayment = "Tạm ứng";
                string advancePaymentUrl = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/AdvancePayment.aspx";

                string repayment = "Hoàn ứng";
                string repaymentUrl = web.ServerRelativeUrl.TrimEnd('/') + "/SitePages/Repayment.aspx";
                
                // Get the Quick Launch headings.
                SPNavigationNodeCollection ql = web.Navigation.QuickLaunch;

                // If a Resources heading exists, get it.
                SPNavigationNode heading = ql
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Title == headingTitle);

                // If the Resources heading does not exist, create it.
                if (heading == null)
                {
                    heading = new SPNavigationNode(headingTitle, headingUrl);
                    heading = ql.AddAsFirst(heading);
                }

                // If the heading has a SharePoint Dev Center item, get it.
                SPNavigationNode item = heading
                    .Children
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Url == purchaseUrl);

                // If the item does not exist, create it.
                if (item == null)
                {
                    item = new SPNavigationNode(purchase, purchaseUrl, true);
                    item = heading.Children.AddAsLast(item);
                }
                //2
                item = heading
                    .Children
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Url == purchaseUrlCEO);

                // If the item does not exist, create it.
                if (item == null)
                {
                    item = new SPNavigationNode(purchaseCEO, purchaseUrlCEO, true);
                    item = heading.Children.AddAsLast(item);
                }
                //3
                item = heading
                    .Children
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Url == paymentUrl);

                // If the item does not exist, create it.
                if (item == null)
                {
                    item = new SPNavigationNode(payment, paymentUrl, true);
                    item = heading.Children.AddAsLast(item);
                }
                //4
                item = heading
                    .Children
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Url == advancePaymentUrl);

                // If the item does not exist, create it.
                if (item == null)
                {
                    item = new SPNavigationNode(advancePayment, advancePaymentUrl, true);
                    item = heading.Children.AddAsLast(item);
                }
                //5
                item = heading
                    .Children
                    .Cast<SPNavigationNode>()
                    .FirstOrDefault(n => n.Url == repaymentUrl);

                // If the item does not exist, create it.
                if (item == null)
                {
                    item = new SPNavigationNode(repayment, repaymentUrl, true);
                    item = heading.Children.AddAsLast(item);
                }
            }
            catch (Exception ex)
            {
            }
        }

        #endregion Functions
    }
}
